package main

import (
	"WsPorxy"
	"flag"
	"fmt"
	"log"
	"net/http"
	_ "net/http/pprof"
	"os"
	"os/signal"
	"runtime"
	"strings"
	"syscall"
	"time"
	"utils"

	"golang.org/x/net/websocket"
)

//配置文件
var pcfgpath *utils.Config
var AppName string = "WebSocketProxy"
var g_ipList *utils.SafeStrMap
var g_SocketMap *utils.SafeStrMap

func main() {

	fmt.Println("webSocketProxy version 1.0.")

	g_ipList = utils.MakeNewSafeStrMap()
	g_SocketMap = utils.MakeNewSafeStrMap()

	//开启多核
	runtime.GOMAXPROCS(runtime.NumCPU())
	//创建日志
	InitDefenseSysLog()
	//读取配置
	DefaultReadProxyConfig()

	fmt.Println("等待监听地址:")
	go NewProxyWsServer()

	//远程获取pprof数据
	go func() {
		log.Println(http.ListenAndServe(":8080", nil))
	}()

	time.Sleep(100)
	//默认配置文件
	fmt.Println("代理正在运行中")
	//select {} // 阻塞
	//阻塞，等待对应的信号量 syscall.SIGHUP, syscall.SIGINT, syscall.SIGKILL, syscall.SIGTERM, syscall.SIGQUIT
	s := WaitForSignal()
	fmt.Println(fmt.Sprintf("gwServer signal got: %v", s))
}

//默认读取代理配置
func DefaultReadProxyConfig() {

	//解析路径
	CfgFile := flag.String("cfg", "proxycfg.ini", "config file for qp")
	flag.Parse()

	//读取配置信息
	MainName := "proxycfg"
	pcfgpath = utils.SetConfig(*CfgFile)
	proxyCnt := pcfgpath.GetValueInt(MainName, "PorxyCnt")

	fmt.Println("读取默认代理设置数量", proxyCnt)

	for i := 0; i < proxyCnt; i++ { //
		PorxyAddr := pcfgpath.GetValueString(MainName, fmt.Sprintf("TargetIp%d", i))
		CheckRecvString(PorxyAddr, nil)
	}
}

//初始化日志
func InitDefenseSysLog() bool {

	if utils.SysLog == nil {
		utils.SysLog = utils.MakeNewMyLog("Systemlogs", "SystemLog", 50000000, 15)
	}

	return true
}

//系统中断
func WaitForSignal() os.Signal {
	signalChan := make(chan os.Signal, 1)
	defer close(signalChan)

	signal.Notify(signalChan, syscall.SIGHUP, syscall.SIGINT, syscall.SIGKILL, syscall.SIGTERM, syscall.SIGQUIT) //等到上述信号才停止函数
	s := <-signalChan                                                                                            //返回该信号
	signal.Stop(signalChan)                                                                                      //这些信号再不发给signalChan管道
	return s
}

func NewProxyWsServer() {

	http.Handle("/Proxy", websocket.Handler(ProxyEcho))

	if err := http.ListenAndServe(":9663", nil); err != nil {
		utils.SysLog.PutLineAsLog(fmt.Sprintf(":%s", err))
	}
}

func ProxyEcho(ws *websocket.Conn) {

	for {
		//设置超时
		ws.SetReadDeadline(time.Now().Add(time.Second * 5))

		var reply string
		if err := websocket.Message.Receive(ws, &reply); err != nil {
			break
		}
		fmt.Println(fmt.Sprintf("ProxyIp:%s", reply))

		CheckRecvString(reply, ws)
		ws.Close()
	}
}

func CheckRecvString(str string, clientWs *websocket.Conn) {

	if strings.Contains(str, "CancelProxy") { //撤销代理
		CancelProxy(str, clientWs)
	} else if strings.Contains(str, "GetListIp") { //查询代理
		GetListIp(str, clientWs)
	} else if strings.Contains(str, "msgok") { //发送维护公告
		Maintenance(str, clientWs)
	} else if strings.Contains(str, "msgcancel") { //取消维护
		CancelMaintenance(str, clientWs)
	} else { //增加代理
		AddProxyIp(str, clientWs)
	}
}

//撤销代理
func CancelProxy(str string, clientWs *websocket.Conn) {
	s := strings.Split(str, " ")

	if g_SocketMap.IsExist(s[1]) {
		fmt.Println("取消端口", s[1])
		//取消代理
		value := g_SocketMap.Get(s[1])
		value.(*WsPorxy.WebSocketControl).CancelProxy()
		g_SocketMap.Remove(s[1])
		g_ipList.Remove(s[1])
	} else {
		if clientWs != nil {
			websocket.Message.Send(clientWs, "撤销的代理不存在")
		}
	}
}

//查询代理列表
func GetListIp(str string, clientWs *websocket.Conn) {
	//返回list 列表
	var SendData string
	if g_ipList.Size() > 0 {
		g_ipList.EachItem(func(key string, value interface{}) {
			ipproxy := value.(string)
			SendData += ipproxy
			SendData += "/"
		})
		fmt.Println(SendData)
		if clientWs != nil {
			websocket.Message.Send(clientWs, SendData)
		}
	}
}

//增加代理
func AddProxyIp(str string, clientWs *websocket.Conn) {
	s := strings.Split(str, " ")
	if len(s) == 2 {
		//檢查代理是否存在
		if g_ipList.IsExist(s[0]) {
			websocket.Message.Send(clientWs, "代理地址已經存在")
		} else {
			WsScoket := WsPorxy.NewWebSocketControl(s[0], s[1])
			go WsScoket.NewWsServer()
			g_ipList.Push(s[0], str)
			g_SocketMap.Push(s[0], WsScoket)
			if clientWs != nil {
				websocket.Message.Send(clientWs, "代理設置成功")
			}
		}
	} else {
		fmt.Println("跳转地址格式错误")
		if clientWs != nil {
			websocket.Message.Send(clientWs, "跳轉格式錯誤")
		}
	}
}

//维护公告
func Maintenance(str string, clientWs *websocket.Conn) {
	s := strings.Split(str, "/")
	if len(s) == 2 {
		g_SocketMap.EachItem(func(key string, value interface{}) {
			value.(*WsPorxy.WebSocketControl).MaintenanceMessage(s[1])
		})
		if clientWs != nil {
			websocket.Message.Send(clientWs, "维护公告设置成功")
		}
	}
}

//取消维护
func CancelMaintenance(str string, clientWs *websocket.Conn) {
	fmt.Println("进入取消维护")
	g_SocketMap.EachItem(func(key string, value interface{}) {
		value.(*WsPorxy.WebSocketControl).CancelMaintenanceMessage()
	})
	if clientWs != nil {
		websocket.Message.Send(clientWs, "取消维护设置成功")
	}
}
